/**
 * Copyright (c) 2011 Tomi Paananen.
 *
 * Part of Quick Gestures engine library.
 */

// Own header
#include "storagemanager.h"

// Qt includes
#include <QFile>

// qgengine includes
#include "gesture.h"
#include "xmlparser.h"
#include "qgtrace.h"

using namespace QGEngine;


/*!
  \class StorageManager
  \brief Storage interface for loading and saving gesture sets.
*/


/*!
  Constructor.
*/
StorageManager::StorageManager(QObject *parent /* = 0 */)
    : QObject(parent),
      m_parser(0)
{
    m_parser = new XmlParser(this);

    connect(m_parser, SIGNAL(progress(int)),
            this, SLOT(handleProgressChanged(int)));
    connect(m_parser, SIGNAL(gestureParsed(Gesture*)),
            this, SIGNAL(gestureRead(Gesture*)));
}


/*!
  Destructor.
*/
StorageManager::~StorageManager()
{
    deleteGestures();
}


/*!
  Appends the loaded gestures into \a gestureSet and clears the internal list.
  Note: The ownership of the gestures is transferred to the caller!
  Returns the number of appended gestures.
*/
int StorageManager::getGestures(QList<Gesture*> &gestureSet)
{
    const int count(m_gestureSet.count());

    if (count) {
        gestureSet += m_gestureSet;
    }

    m_gestureSet.clear();
    return count;
}


/*!
  Deletes the internal gesture set. Note: This method should only be called if
  the ownerhip of the gesture has not been transferred!
*/
void StorageManager::deleteGestures()
{
    if (m_gestureSet.count()) {
        DEBUG_INFO("Deleting" << m_gestureSet.count() << "gestures.");
        qDeleteAll(m_gestureSet);
        m_gestureSet.clear();
    }
}


/*!
  Loads gestures from \a filepath. Returns QGEngine::NoError if successful,
  an error code otherwise.
*/
int StorageManager::load(const QString &filepath)
{
    DEBUG_INFO(filepath);

    // Delete old gestures if any exist.
    deleteGestures();

    QFile file(filepath);
    int retVal(NoError);

    if (file.open(QFile::ReadOnly)) {
        int error = m_parser->readGestures(&file, m_gestureSet);

        if (error != NoError) {
            // Failed to (fully) parse the gestures! Store the error code.
            DEBUG_INFO("Catched an error code: " << error);
            retVal = error;
        }

        file.close();
    }
    else {
        DEBUG_INFO("Failed to open file \"" << filepath << "\" for reading!");
        retVal = FileError;
    }

    return retVal;
}


/*!
  Saves \a gestureSet into \a filepath. Returns QGEngine::NoError if successful,
  an error code otherwise.
*/
int StorageManager::save(const QString &filepath, QList<Gesture*> &gestureSet)
{
    if (!gestureSet.count()) {
        DEBUG_INFO("The given gesture set is empty!");
        return InvalidArgument;
    }

    QFile file(filepath);
    int retVal(NoError);

    if (file.open(QFile::WriteOnly)) {
        int error = m_parser->writeGestures(&file, gestureSet);

        if (error != NoError) {
            // Failed to (fully) write the gestures! Store the error code.
            DEBUG_INFO("Catched an error code: " << error);
            retVal = error;
        }

        file.close();
    }
    else {
        DEBUG_INFO("Failed to open file \"" << filepath << "\" for reading!");
        retVal = FileError;
    }

    return retVal;
}


/*!
  Clears the gesture set. This method should be called if the ownership of the
  gestures is taken without calling StorageManager::getGestures().
*/
void StorageManager::clear()
{
    m_gestureSet.clear();
}


/*!
  Gets called when an operation progresses.
*/
void StorageManager::handleProgressChanged(int percentsComplete)
{
    static int prevValue(0);

    if (percentsComplete != prevValue || percentsComplete == 100) {
        prevValue = percentsComplete;
        emit progress(percentsComplete);
    }
}


// End of file.
